package pro2_transport.P2_chat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

/**
 * @program: netty
 * @description:
 * @author: zy
 * @create: 2025-08-28 14:41
 */
public class ChatServer {
    private Selector selector;
    private ServerSocketChannel serverChannel;
    private static final int PORT = 9999;

    public void start() throws IOException {
        // 1. 打开 selector 和 ServerSocketChannel
        selector = Selector.open();
        serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(PORT));

        // 2. 注册 accept 事件
        serverChannel.register(selector, SelectionKey.OP_ACCEPT);
        System.out.println("聊天室服务器启动，端口: " + PORT);

        // 3. 循环监听事件
        while (true) {
            selector.select();  // 阻塞直到有事件
            Iterator<SelectionKey> keys = selector.selectedKeys().iterator();

            while (keys.hasNext()) {
                SelectionKey key = keys.next();
                keys.remove();

                if (key.isAcceptable()) {
                    // 处理新客户端连接
                    SocketChannel client = serverChannel.accept();
                    client.configureBlocking(false);
                    client.register(selector, SelectionKey.OP_READ);
                    System.out.println("新用户加入: " + client.getRemoteAddress());
                }
                else if (key.isReadable()) {
                    // 处理客户端消息
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    int read = client.read(buffer);

                    if (read > 0) {
                        buffer.flip();
                        String msg = new String(buffer.array(), 0, buffer.limit());
                        System.out.println("收到消息: " + msg.trim());


                        broadcast(client, msg);
                    } else if (read == -1) {
                        // 客户端关闭
                        System.out.println("用户离开: " + client.getRemoteAddress());
                        key.cancel();
                        client.close();
                    }
                }
            }
        }
    }

    // 广播消息给所有客户端
    private void broadcast(SocketChannel sender, String msg) throws IOException {
        for (SelectionKey key : selector.keys()) {
            Channel target = key.channel();
            //不能发给自己 target!=sender
            if (target instanceof SocketChannel && target != sender) {
                SocketChannel dest = (SocketChannel) target;
                dest.write(ByteBuffer.wrap(msg.getBytes()));
            }
        }
    }

    public static void main(String[] args) throws IOException {
        new ChatServer().start();
    }
}
